package com.arpa.oms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.arpa.core.utils.collection.CollectionUtil;
import com.arpa.core.utils.misc.IdGenerator;
import com.arpa.core.utils.number.NumberUtil;
import com.arpa.core.web.Result;
import com.arpa.ntocc.common.common.cache.PartyCache;
import com.arpa.ntocc.common.common.cache.ShipmentCache;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.ntocc.common.domain.entity.Shipment;
import com.arpa.ntocc.common.service.IShipmentService;
import com.arpa.oms.domain.dto.OmsGoodsDTO;
import com.arpa.oms.domain.dto.OmsGoodsRelationExcleDTO;
import com.arpa.oms.domain.entity.OmsGoodsRelationItem;
import com.arpa.oms.domain.enums.OmsGoodTypeEnum;
import com.arpa.oms.domain.vo.OmsGoodsRelationExcleVO;
import com.arpa.oms.domain.vo.OmsGoodsVO;
import com.arpa.oms.service.IOmsGoodsRelationItemService;
import com.arpa.oms.service.IOmsGoodsRelationService;
import com.arpa.wms.cache.GoodsUnitConversionCache;
import com.arpa.wms.cache.ImportTempCache;
import com.arpa.wms.cache.UnitCache;
import com.arpa.wms.domain.consts.NumConst;
import com.arpa.wms.domain.consts.PropertyConst;
import com.arpa.wms.domain.dto.GoodsDTO;
import com.arpa.wms.domain.entity.Goods;
import com.arpa.wms.domain.entity.GoodsUnit;
import com.arpa.wms.domain.entity.GoodsUnitConversion;
import com.arpa.wms.domain.enums.StatusEnum;
import com.arpa.wms.mapper.GoodsMapper;
import com.arpa.wms.service.IGoodsService;
import com.arpa.wms.service.IGoodsUnitService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.arpa.wms.domain.consts.NumConst.NUM_THREE;
import static com.arpa.wms.domain.consts.NumConst.NUM_ZERO;
import static com.arpa.wms.domain.consts.TipConst.*;

/**
 * <p>
 * OMS商品关系表 服务实现类
 * </p>
 *
 * @author spb
 * @since 2021-07-22
 */
@Service
public class OmsGoodsRelationServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements IOmsGoodsRelationService {
    @Resource
    private PartyCache partyCache;
    @Resource
    private ShipmentCache shipmentCache;
    @Resource
    private UnitCache unitCache;
    @Resource
    private GoodsUnitConversionCache goodsUnitConversionCache;
    @Autowired
    private IShipmentService shipmentService;

    @Autowired
    private IOmsGoodsRelationItemService iOmsGoodsRelationItemService;
    @Autowired
    private IGoodsService iGoodsService;
    @Autowired
    private IGoodsUnitService iGoodsUnitService;
    @Autowired
    private ImportTempCache importTempCache;

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean create(OmsGoodsDTO entity) {
        if (StringUtils.isBlank(entity.getGoodCode())) {
            throw new ServiceException("商品编码不能为空");
        }
        List<Goods> list = iGoodsService.list(new QueryWrapper<Goods>().lambda().eq(Goods::getGoodCode, entity.getGoodCode()));
        if (CollectionUtil.isNotEmpty(list)) {
            throw new ServiceException("商品编码已存在");
        }

        // 校验是否有重复项
        validRepeatGoods(entity.getGoodsItems());

        Goods goods = new Goods();
        BeanUtils.copyProperties(entity, goods);
        goods.setCreatedBy(UserUtil.getCode());
        goods.setModifiedBy(UserUtil.getCode());
        String loginName = partyCache.translate(UserUtil.getCode());
        goods.setCreatedName(loginName);
        goods.setModifiedName(loginName);
        goods.setStatus(StatusEnum.UNACTIVE.getValue());
        goods.setShipmentCode(goods.getShipmentCode());
        goods.setShipmentName(shipmentCache.translate(goods.getShipmentCode()));
        goods.setCode(IdUtil.simpleUUID());
        goods.setRecordType(OmsGoodTypeEnum.GOOD_TYPE_COMPOSE.getCode());
        goods.setQuality(BigDecimal.ONE);
        goods.setStorageStrategy(NUM_ZERO + "");
        boolean flag = this.save(goods);

        if (flag) {
            entity.getGoodsItems().forEach(r -> {
                r.setGoodsRelationCode(goods.getCode());
                r.setCode(IdUtil.simpleUUID());
                r.setModifiedBy(UserUtil.getCode());
                r.setCreatedBy(UserUtil.getCode());
                r.setModifiedName(loginName);
                r.setCreatedName(loginName);
                r.setPlanBasicQuantity(r.getPlanQuantity());
            });
            iOmsGoodsRelationItemService.saveBatch(entity.getGoodsItems());
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int updateByCode(OmsGoodsDTO entity) {
        if (StringUtils.isBlank(entity.getGoodCode())) {
            throw new ServiceException("商品编码不能为空");
        }
        List<Goods> list = iGoodsService.list(new QueryWrapper<Goods>().lambda().eq(Goods::getGoodCode, entity.getGoodCode()).ne(Goods::getCode, entity.getCode()));
        if (CollectionUtil.isNotEmpty(list)) {
            throw new ServiceException("商品编码已存在");
        }
        // 校验是否有重复项
        validRepeatGoods(entity.getGoodsItems());
        Goods goods = new Goods();
        BeanUtils.copyProperties(entity, goods);
        goods.setModifiedBy(UserUtil.getCode());
        String loginName = partyCache.translate(UserUtil.getCode());
        goods.setModifiedName(loginName);
        goods.setStatus(StatusEnum.UNACTIVE.getValue());
        goods.setShipmentCode(entity.getShipmentCode());
        goods.setRecordType(OmsGoodTypeEnum.GOOD_TYPE_COMPOSE.getCode());
        int i = baseMapper.update(goods, new QueryWrapper<Goods>().lambda().eq(Goods::getCode, entity.getCode()));
        if (i > 0) {
            // 先删除执之前绑定商品
            iOmsGoodsRelationItemService.remove(new QueryWrapper<OmsGoodsRelationItem>().lambda().eq(OmsGoodsRelationItem::getGoodsRelationCode, entity.getCode()).ne(OmsGoodsRelationItem::getDeleted, NumConst.NUM_ONE));

            entity.getGoodsItems().forEach(r -> {
                r.setCode(IdUtil.simpleUUID());
                r.setGoodsRelationCode(goods.getCode());
                r.setModifiedBy(UserUtil.getCode());
                r.setCreatedBy(UserUtil.getCode());
                r.setModifiedName(loginName);
                r.setCreatedName(loginName);
                r.setPlanBasicQuantity(r.getPlanQuantity());
            });
            iOmsGoodsRelationItemService.saveBatch(entity.getGoodsItems());
        }
        return i;
    }

    @Override
    public Integer listCount(GoodsDTO goodsDTO) {
        LambdaQueryWrapper<Goods> queryWrapper = getQueryWrapper(new QueryWrapper<>(), goodsDTO);
        queryWrapper.eq(Goods::getRecordType, OmsGoodTypeEnum.GOOD_TYPE_COMPOSE.getCode());
        return baseMapper.selectCount(queryWrapper);
    }

    @Override
    public List<Goods> listPage(GoodsDTO goodsDTO) {
        QueryWrapper query = new QueryWrapper();
        if (StringUtils.isNotBlank(goodsDTO.getSortField())) {
            if (StringUtils.isNotBlank(goodsDTO.getSortType()) && goodsDTO.getSortType().toLowerCase().equals("asc")) {
                query.orderByAsc(goodsDTO.getSortField());
            } else {
                query.orderByDesc(goodsDTO.getSortField());
            }
        } else {
            query.orderByDesc("gmt_created");
        }
        LambdaQueryWrapper<Goods> queryWrapper = getQueryWrapper(query, goodsDTO);
        queryWrapper.eq(Goods::getRecordType, OmsGoodTypeEnum.GOOD_TYPE_COMPOSE.getCode());
        int start = (goodsDTO.getPageNum()-1)*goodsDTO.getPageSize();
        queryWrapper.last("limit " + start + " , " + goodsDTO.getPageSize());
        List<Goods> list = baseMapper.selectList(queryWrapper);
        if(CollectionUtil.isNotEmpty(list)) {
            list.forEach(v -> v.setBasicUnitName(unitCache.translate(v.getUnitCode())));
        }
        return list;
    }

    @Override
    @Transactional
    public Map<String, Integer> batchUpdateStatus(List<String> codes, String value) {
        Map<String, Integer> resultData = new HashMap<>();
        resultData.put(PropertyConst.SUCCESS, 0);
        List<Goods> list = this.list(new QueryWrapper<Goods>().lambda().in(Goods::getCode, codes));
        String loginName = partyCache.translate(UserUtil.getCode());
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(v -> {
                v.setStatus(value);
                v.setModifiedBy(UserUtil.getCode());
                v.setModifiedName(loginName);
            });
            boolean flag = this.updateBatchById(list);
            if (flag) {
                resultData.put(PropertyConst.SUCCESS, list.size());
            }
        }
        return resultData;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Map<String, Integer> deleteByCodes(List<String> codes) {
        Map<String, Integer> resultData = new HashMap<>();
        int num = baseMapper.delete(new QueryWrapper<Goods>().lambda().in(Goods::getCode, codes));
        if (num > 0) {
            iOmsGoodsRelationItemService.remove(new QueryWrapper<OmsGoodsRelationItem>().lambda().in(OmsGoodsRelationItem::getCode, codes));
        }
        resultData.put(PropertyConst.SUCCESS, num);
        return resultData;
    }

    @Override
    public List<OmsGoodsRelationExcleVO> goodsRelationExcelView(List<OmsGoodsRelationExcleDTO> list) {
        // 导入号
        String importCode = IdUtil.simpleUUID();

        List<Object> allGoodsList =  baseMapper.selectObjs(new QueryWrapper<Goods>().lambda().select(Goods::getGoodCode).eq(Goods::getShipmentCode, UserUtil.getLoginWarehouseCodeOrShipmentCode()));

        OmsGoodsRelationExcleDTO firstRow = list.get(NUM_ZERO);
        // 校验重复项
        Map<String, Integer> repeatData = new HashMap<>();

        // 校验 入驻商
        Shipment shipment = validateShipment(firstRow);

        // 用于校验商品
        List<Goods> goodsList = iGoodsService.list(new QueryWrapper<Goods>().lambda().eq(Goods::getShipmentCode, shipment.getPartyCode()).eq(Goods::getStatus, StatusEnum.ACTIVE.getValue()));
        if (CollectionUtils.isEmpty(goodsList)) {
            throw new ServiceException(SHIPMENT_NOT_GOODS);
        }
        Set<String> baseUnitList = goodsList.stream().map(v -> v.getUnitCode()).collect(Collectors.toSet());
        List<GoodsUnit> goodsUnitList = iGoodsUnitService.list(new QueryWrapper<GoodsUnit>().lambda().in(GoodsUnit::getCode, baseUnitList));
        Map<String, GoodsUnit> goodsUnitMap = goodsUnitList.stream().collect(Collectors.toMap(GoodsUnit::getCode, e -> e, (key1, key2) -> key2));
        Map<String, GoodsUnit> goodsCodeKeyUnitMap = new HashMap<>();
        goodsList.forEach(v->{
            goodsCodeKeyUnitMap.put(v.getCode(), goodsUnitMap.get(v.getUnitCode()));
        });
        final Map<String, Goods> goodsMap = goodsList.stream().collect(Collectors.toMap(Goods::getGoodCode, e -> e, (key1, key2) -> key2));

        // 遍历序号
        AtomicInteger indexes = new AtomicInteger(0);
        Map<String, BigDecimal> priceMap = new HashMap<>();
        List<OmsGoodsRelationExcleDTO> vaildList = list.stream().map(temp -> {
            temp.setShipmentName(shipment.getUserName());
            Integer index = indexes.getAndIncrement();
            //必填校验， 由于代码校验要求单个方法if校验不能超过15个，所以拆分为两次校验
            validateNotBlank(temp, index);
            // 校验是否有效值
            validateNotExist(allGoodsList, goodsMap, goodsCodeKeyUnitMap, temp, index, shipment);

            //校验同一个组合商品，售价是否一致
            if (priceMap.containsKey(temp.getGoodRalationCode()) && temp.getGoodRelationPrice().compareTo(priceMap.get(temp.getGoodRalationCode())) != 0) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + DELIVERY_PRICE + DELIVERY_PRICE_NOT_SAME);
            }
            priceMap.put(temp.getGoodRalationCode(), temp.getGoodRelationPrice());
            return temp;
        }).collect(Collectors.toList());
        //自动合并相同商品
        List<OmsGoodsRelationExcleVO> finalList = autoMergeSameGoods(vaildList, importCode);
        Map<String, List<OmsGoodsRelationExcleVO>> relationMap = finalList.stream().collect(Collectors.groupingBy(OmsGoodsRelationExcleVO::getGoodRalationCode, Collectors.toList()));
        for (Map.Entry<String, List<OmsGoodsRelationExcleVO>> m : relationMap.entrySet()) {
            if (CollectionUtils.isEmpty(m.getValue()) || m.getValue().size() < 2) {
                throw new ServiceException(GOODS_RELATION_CODE + "【" + m.getKey() + "】" + "商品种类需要大于1");
            }
        }

        // 保存到缓存中
        importTempCache.putTempData(importCode, finalList);
        return finalList;
    }

    @Override
    public OmsGoodsVO getInfoByCode(String code) {
        OmsGoodsVO omsGoodsVO = new OmsGoodsVO();
        Goods goods = baseMapper.selectOne(new QueryWrapper<Goods>().lambda().eq(Goods::getCode, code));
        if (goods != null) {
            BeanUtils.copyProperties(goods, omsGoodsVO);
            List<OmsGoodsRelationItem> items = iOmsGoodsRelationItemService.list(new QueryWrapper<OmsGoodsRelationItem>().lambda().eq(OmsGoodsRelationItem::getGoodsRelationCode, code).orderByAsc(OmsGoodsRelationItem::getGoodsName));
            items.stream().forEach(r->{
                List<GoodsUnitConversion> goodsUnitConversions = goodsUnitConversionCache.get(r.getGoodsCode());
                r.setGoodsUnitConversionList(goodsUnitConversions);
            });
            omsGoodsVO.setGoodsItems(items);
        }
        return omsGoodsVO;
    }

    @Override
    public List<Map<String, Object>> searchPure(String keywords, String shipmentCode) {
        List<Goods> list = baseMapper.selectList(new QueryWrapper<Goods>().lambda().eq(Goods::getShipmentCode, shipmentCode).eq(Goods::getRecordType, OmsGoodTypeEnum.GOOD_TYPE_COMPOSE.getCode()).eq(Goods::getStatus, StatusEnum.ACTIVE.getValue()).and(wrapper -> wrapper.like(Goods::getName, keywords).or().like(Goods::getGoodCode, keywords)));
        if (CollectionUtil.isNotEmpty(list)) {
//            List<String> goodsRelationList = list.stream().map(v -> v.getCode()).collect(Collectors.toList());
//            List<OmsGoodsRelationItem> itemList = iOmsGoodsRelationItemService.list(new QueryWrapper<OmsGoodsRelationItem>().lambda().in(OmsGoodsRelationItem::getGoodsRelationCode, goodsRelationList));
            List<Map<String, Object>> result = list.stream().map(BeanUtil::beanToMap).collect(Collectors.toList());
            result.stream().forEach(map -> {
//                Map<String, Object> map = new HashMap<>();
//                map.put("name", v.getName());
//                map.put("goodCode", v.getGoodCode());
//                map.put("barCode", "");
                map.put("purchase", 1);
//                map.put("recordType", OmsGoodTypeEnum.GOOD_TYPE_COMPOSE.getCode());
//                List<OmsGoodsRelationItem> items = itemList.stream().filter(i -> v.getCode().equals(i.getGoodsRelationCode())).collect(Collectors.toList());
//                List<Map<String, Object>> goodMap = new ArrayList<>();
//                if (CollectionUtil.isNotEmpty(itemList)) {
//                    for (OmsGoodsRelationItem item : items) {
//                        goodMap.add(goodsCache.get(item.getGoodsCode()));
//                    }
//                }
//                map.put("goodsList", goodMap);
//                return map;
            });
            return result;
        }
        return null;
    }

    @Override
    public List<Map<String, Object>> searchGoods(String goodName, String goodCode,String goodBarCode, String shipmentCode){
        List<Goods> list = baseMapper.selectList(new QueryWrapper<Goods>().lambda().eq(Goods::getShipmentCode, shipmentCode)
                .eq(Goods::getRecordType, OmsGoodTypeEnum.GOOD_TYPE_COMPOSE.getCode()).eq(Goods::getStatus, StatusEnum.ACTIVE.getValue())
                .and(wrapper -> wrapper.like(Goods::getName, goodName).like(Goods::getGoodCode, goodCode).like(Goods::getBarCode, goodBarCode)));
        if (CollectionUtil.isNotEmpty(list)) {
            List<Map<String, Object>> result = list.stream().map(BeanUtil::beanToMap).collect(Collectors.toList());
            result.stream().forEach(map -> {
                map.put("purchase", 1);
            });
            return result;
        }
        return null;
    }

    @Override
    public Result importGoodsRelation(String importCode) {
        // 根据导入码，获取导入缓存
        List<OmsGoodsRelationExcleVO> tempData = importTempCache.getTempData(importCode, OmsGoodsRelationExcleVO.class);
        // 判断数据，如果没有了，则直接返回
        if(tempData == null){
            return Result.error("缓存数据不存在，或超过有效时间，缓存已被清除，请重新导入。");
        }
        Set<String> goodsRelationList = tempData.stream().map(v -> v.getGoodRalationCode()).collect(Collectors.toSet());
        List<Goods> goodsList = new ArrayList<>();
        String loginName = partyCache.translate(UserUtil.getCode());
        Goods goods;
        for (String goodCode : goodsRelationList) {
            goods = new Goods();
            goods.setCode(IdGenerator.uuid2());
            goods.setGoodCode(goodCode);
            goods.setRecordType(OmsGoodTypeEnum.GOOD_TYPE_COMPOSE.getCode());
            goods.setStatus(StatusEnum.UNACTIVE.getValue());
            goods.setQuality(BigDecimal.ONE);
            goods.setSale(NUM_ZERO);
            goods.setPurchase(NUM_ZERO);
            goods.setStorageStrategy(NUM_ZERO + "");
            goods.setCreatedBy(UserUtil.getCode());
            goods.setModifiedBy(UserUtil.getCode());
            goods.setCreatedName(loginName);
            goods.setModifiedName(loginName);
            goodsList.add(goods);
        }
        Map<String, Goods> goodsMap = goodsList.stream().collect(Collectors.toMap(Goods::getGoodCode, e -> e));
        List<OmsGoodsRelationItem> itemList = new ArrayList<>();
        List<Goods> newGoods = new ArrayList<>();
        for (OmsGoodsRelationExcleVO vo : tempData) {
            OmsGoodsRelationItem item = new OmsGoodsRelationItem();
            Goods g = vo.getGoods();
            if (g == null) {
                throw new ServiceException("导入异常");
            }
            BeanUtil.copyProperties(g, item);
            item.setGoodsCode(g.getCode());
            item.setGoodsBarCode(g.getBarCode());
            item.setGoodsName(g.getName());
            item.setExpirationQuantity(g.getQuality());
            item.setBasicUnit(g.getUnitCode());
            item.setBasicUnitName(unitCache.translate(g.getUnitCode()));
            item.setUnitConvertQuantity(BigDecimal.ONE);
            item.setSaleUnit(item.getBasicUnit());
            item.setSaleUnitName(item.getBasicUnitName());
            item.setPlanQuantity(vo.getQuantity());
            item.setPlanBasicQuantity(vo.getQuantity());
            Goods relationGoods = goodsMap.get(vo.getGoodRalationCode());
            if (relationGoods != null) {
                item.setCreatedBy(relationGoods.getCreatedBy());
                item.setCreatedName(relationGoods.getCreatedName());
                item.setModifiedBy(relationGoods.getModifiedBy());
                item.setModifiedName(relationGoods.getModifiedName());
                item.setGoodsRelationCode(relationGoods.getCode());
                item.setCode(IdUtil.simpleUUID());
                item.setModifiedBy(UserUtil.getCode());
                item.setCreatedBy(UserUtil.getCode());
                item.setModifiedName(relationGoods.getModifiedName());
                item.setCreatedName(relationGoods.getCreatedName());
                item.setPlanBasicQuantity(item.getPlanQuantity());
                if (StringUtils.isBlank(relationGoods.getName())) {
                    relationGoods.setName(vo.getGoodRalationName());
                    relationGoods.setDeliveryPrice(vo.getGoodRelationPrice());
                    relationGoods.setShipmentCode(vo.getShipmentCode());
                    relationGoods.setShipmentName(vo.getShipmentName());
                    relationGoods.setUnitCode(vo.getGoodRelationUnit());
                    relationGoods.setBasicUnitName(vo.getGoodRelationUnitText());
                    newGoods.add(relationGoods);
                }
            } else {
                throw new ServiceException("数据异常");
            }
            item.setCode(IdGenerator.uuid2());
            itemList.add(item);
        }
        iGoodsService.saveBatch(newGoods);
        iOmsGoodsRelationItemService.saveBatch(itemList);

        // 完成导入后删除导入的缓存
        importTempCache.removeCache(importCode);
        return Result.ok();
    }

    private List<OmsGoodsRelationExcleVO> autoMergeSameGoods(List<OmsGoodsRelationExcleDTO> vaildList, String importCode) {
        Map<String, OmsGoodsRelationExcleVO> map = new HashMap<>();
        vaildList.forEach(v -> {
            OmsGoodsRelationExcleVO vo = new OmsGoodsRelationExcleVO();
            BeanUtil.copyProperties(v, vo);
            String key = v.getGoodRalationCode() + v.getGoodCode();
            if (map.containsKey(key)) {
                OmsGoodsRelationExcleVO dto = map.get(key);

                BigDecimal sum = dto.getQuantity().add(v.getQuantity());
                v.setQuantity(sum);
            }
            vo.setImportCode(importCode);
            map.put(key, vo);
        });
        return new ArrayList<>(map.values());
    }

    private void validateNotExist(List<Object> allGoodsList, Map<String, Goods> goodsMap, Map<String, GoodsUnit> goodsCodeKeyUnitMap, OmsGoodsRelationExcleDTO temp, Integer index, Shipment shipment) {
        if (allGoodsList.contains(temp.getGoodRalationCode())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS_RELATION_CODE + COMPOSE_GOODS_HAS);
        }
        Goods goods = goodsMap.get(temp.getGoodCode());
        if (null == goods) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOOD_CODE_NAME + NOT_EXIST);
        }
        temp.setGoods(goods);
        if (!goods.getName().equals(temp.getGoodsName())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOOD_CODE_NAME + YU + GOODS_NAME + NOT_SAMEB);
        }
        if (!goods.getBarCode().equals(temp.getBarCode())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOOD_CODE_NAME + YU + GOODS_BAR_CODE + NOT_SAMEB);
        }
        GoodsUnit goodsUnit = goodsCodeKeyUnitMap.get(goods.getCode());
        if (null == goodsUnit) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS_NOT_HAS_GOODS_UNIT);
        }
        if (!goodsUnit.getUnitName().equals(temp.getBasicUnitName())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOOD_CODE_NAME + YU + BASICUNIT_NAME + NOT_SAMEB);
        }
        temp.setBaseUnitCode(goodsUnit.getCode());
        GoodsUnit unit = unitCache.getByUnitName(temp.getGoodRelationUnitText(), shipment.getPartyCode(),UserUtil.getBranchCode());
        if (unit == null) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + COMPOSE_GOODS + BASICUNIT_NAME + NOT_EXIST);
        } else {
            temp.setGoodRelationUnit(unit.getCode());
        }
    }

    private Shipment validateShipment(OmsGoodsRelationExcleDTO firstRow) {
        if (StringUtils.isBlank(firstRow.getShipmentCode())) {
            throw new ServiceException(TIP_PREFIX + NUM_THREE + LINE + SHIPMENT_SERIAL_NUMBER + NOT_BLANK);
        }
        Shipment shipment = shipmentService.findShipmentByPartyCode(firstRow.getShipmentCode());
        if (shipment == null) {
            throw new ServiceException(SHIPMENT_SERIAL_NUMBER + NOT_EXIST);
        }
        if (!shipment.getPartyCode().equals(UserUtil.getLoginWarehouseCodeOrShipmentCode())) {
            throw new ServiceException(TIP_PREFIX + NUM_THREE + LINE + SHIPMENT_SERIAL_NUMBER + YU + LOGIN_SHIPMENT + NOT_SAMEB);
        }
        // 校验 货主是否审核通过
        if (!NumConst.NUM_THREE.equals(shipment.getAuthStatus())) {
            throw new ServiceException(SHIPMENT_SERIAL_NUMBER + UNAPPROVE_NAME);
        }
        return shipment;
    }

    private void validateNotBlank(OmsGoodsRelationExcleDTO temp, Integer index) {
        // 校验Excel里必填项是否有空值
        if (StrUtil.isBlank(temp.getGoodRalationCode())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS_RELATION_CODE + NOT_BLANK);
        }
        if (StrUtil.isBlank(temp.getGoodRalationName())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS_RELATION_NAME + NOT_BLANK);
        }
        if (StringUtils.isBlank(temp.getGoodRelationUnitText())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + COMPOSE_GOODS + GOODS_UNIT + NOT_BLANK);
        }
        if (StrUtil.isBlank(temp.getShipmentCode())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + SHIPMENT_SERIAL_NUMBER + NOT_BLANK);
        }
        if (StrUtil.isBlank(temp.getGoodCode())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOOD_CODE_NAME + NOT_BLANK);
        }
        if (StrUtil.isBlank(temp.getBarCode())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS_BAR_CODE + NOT_BLANK);
        }
        if (StrUtil.isBlank(temp.getGoodsName())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS_NAME + NOT_BLANK);
        }
        if (StrUtil.isBlank(temp.getBasicUnitName())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + BASICUNIT_NAME + NOT_BLANK);
        }
        if (StrUtil.isBlank(temp.getQuantityStr())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOOD_QUANTITY + NOT_BLANK);
        } else {
            if (!NumberUtil.isNumber(temp.getQuantityStr())) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOOD_QUANTITY + FORMAT_ERROR);
            }
            String s = "^[+]{0,1}(\\d+)$";
            if (!temp.getQuantityStr().matches(s)) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOOD_QUANTITY + NOT_BE + NUMBER_INTEGER);
            }
            BigDecimal quantity = new BigDecimal(temp.getQuantityStr());
            if (quantity == null || quantity.compareTo(BigDecimal.ZERO) < 1) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOOD_QUANTITY + NOT_AVAILABLE);
            }
            temp.setQuantity(quantity);
        }
        if (StrUtil.isBlank(temp.getGoodRelationPriceStr())) {
            throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS_RELATION_PRICE + NOT_BLANK);
        } else {
            if (!NumberUtil.isNumber(temp.getGoodRelationPriceStr())) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS_RELATION_PRICE + FORMAT_ERROR);
            }
            BigDecimal price = new BigDecimal(temp.getGoodRelationPriceStr());
            if (price == null || price.compareTo(BigDecimal.ZERO) < 0) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + DELIVERY_PRICE + NOT_AVAILABLE);
            }
            if (getNumberOfDecimalPlaces(price) > 2) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + DELIVERY_PRICE + PRICE_TWO_DECIMAL);
            }
            temp.setGoodRelationPrice(price);
        }
    }

    private int getNumberOfDecimalPlaces(BigDecimal bigDecimal) {
        String string = bigDecimal.stripTrailingZeros().toPlainString();
        int index = string.indexOf(".");
        return index < 0 ? 0 : string.length() - index - 1;
    }

    private LambdaQueryWrapper<Goods> getQueryWrapper(QueryWrapper query, GoodsDTO goodsDTO) {
        LambdaQueryWrapper<Goods> queryWrapper = query.lambda();
        if (StringUtils.isNotBlank(goodsDTO.getStatus())) {
            queryWrapper.eq(Goods::getStatus, goodsDTO.getStatus());
        }
        if (StringUtils.isNotBlank(goodsDTO.getShipmentCode())) {
            queryWrapper.eq(Goods::getShipmentCode, goodsDTO.getShipmentCode());
        } else {
            queryWrapper.eq(Goods::getShipmentCode, UserUtil.getLoginWarehouseCodeOrShipmentCode());
        }
        if (StringUtils.isNotBlank(goodsDTO.getModifiedName())) {
            queryWrapper.like(Goods::getModifiedName, goodsDTO.getModifiedName());
        }
        if (StringUtils.isNotBlank(goodsDTO.getCreatedName())) {
            queryWrapper.like(Goods::getCreatedName, goodsDTO.getCreatedName());
        }
        if ((null != goodsDTO.getDeliveryPriceStart()) && (null != goodsDTO.getDeliveryPriceEnd())) {
            queryWrapper.between(Goods::getDeliveryPrice, goodsDTO.getDeliveryPriceStart(), goodsDTO.getDeliveryPriceEnd());
        } else {
            if (null != goodsDTO.getDeliveryPriceStart()) {
                queryWrapper.ge(Goods::getDeliveryPrice, goodsDTO.getDeliveryPriceStart());
            }
            if (null != goodsDTO.getDeliveryPriceEnd()) {
                queryWrapper.le(Goods::getDeliveryPrice, goodsDTO.getDeliveryPriceEnd());
            }
        }

        if ((null != goodsDTO.getGmtCreatedStart()) && (null != goodsDTO.getGmtCreatedEnd())) {
            queryWrapper.between(Goods::getGmtCreated, goodsDTO.getGmtCreatedStart(), goodsDTO.getGmtCreatedEnd());
        } else {
            if (null != goodsDTO.getGmtCreatedStart()) {
                queryWrapper.ge(Goods::getGmtCreated, goodsDTO.getGmtCreatedStart());
            }
            if (null != goodsDTO.getGmtCreatedEnd()) {
                queryWrapper.le(Goods::getGmtCreated, goodsDTO.getGmtCreatedEnd());
            }
        }

        if ((null != goodsDTO.getGmtModifiedStart()) && (null != goodsDTO.getGmtModifiedEnd())) {
            queryWrapper.between(Goods::getGmtCreated, goodsDTO.getGmtModifiedStart(), goodsDTO.getGmtModifiedEnd());
        } else {
            if (null != goodsDTO.getGmtModifiedStart()) {
                queryWrapper.ge(Goods::getGmtModified, goodsDTO.getGmtModifiedStart());
            }
            if (null != goodsDTO.getGmtModifiedEnd()) {
                queryWrapper.le(Goods::getGmtModified, goodsDTO.getGmtModifiedEnd());
            }
        }

        if (StringUtils.isNotBlank(goodsDTO.getName())) {
            queryWrapper.like(Goods::getName, goodsDTO.getName());
        }
        if (StringUtils.isNotBlank(goodsDTO.getGoodCode())) {
            queryWrapper.like(Goods::getGoodCode, goodsDTO.getGoodCode());
        }
        if (StringUtils.isNotBlank(goodsDTO.getUnitCode())) {
            queryWrapper.eq(Goods::getUnitCode, goodsDTO.getUnitCode());
        }

        return queryWrapper;
    }

    private static void validRepeatGoods(List<OmsGoodsRelationItem> relationItems) {
        // 校验是否有重复项
        Map<String, Object> validDuplication = new HashMap<>();
        String validKey;
        for (OmsGoodsRelationItem e : relationItems) {
            validKey = e.getGoodsCode() + "-" + e.getBasicUnit();
            if (validDuplication.containsKey(validKey)) {
                throw new ServiceException("存在重复的商品信息，请确认");
            } else {
                validDuplication.put(validKey, e);
            }
            //判断用户输入的数量个数，如果是小数必须是6位
            BigDecimal planQuantity = e.getPlanQuantity();
            boolean b = compareNumber(planQuantity);
            if (!b) {
                doubleyn(String.valueOf(planQuantity), 6);
            }
        }
    }

    /**
     * 判断是整数还是小数
     *
     * @param number
     * @return
     */
    public static boolean compareNumber(BigDecimal number) {
        if (!"".equals(number) && number != null) {
            if (new BigDecimal(number.intValue()).compareTo(number) == 0) {
                //整数
                return true;
            } else {
                //小数
                return false;
            }
        }
        return false;
    }

    public static boolean doubleyn(String str, int dousize) {
        try {
            double num = Double.valueOf(str);//把字符串强制转换为数字
            if (str.trim().indexOf(".") == -1) {
                return false;
            }
            int fourplace = str.trim().length() - str.trim().indexOf(".") - 1;
            if (fourplace > dousize) {
                throw new ServiceException("数量小数不能大于6位!");
            } else {
                return true;
            }
        } catch (Exception e) {
            throw new ServiceException("存在重复的商品信息，请确认");
        }
    }
}
